<template>
  <!-- 通用导入组件 -->
  <el-dialog
    :title="$t(uploadParams.title)"
    v-model="dg.open"
    append-to-body
    class="app-dialog-container"
    @close="handleClose"
    align-center
    destroy-on-close
    draggable>
    <div v-szd-dialog="[uploadParams.dialogWidth, uploadParams.dialogHeight]" />
    <!-- 导入文件提示信息 -->
    <div v-if="uploadParams.listType === 'picture-card' && uploadParams.acceptTxt" style="padding: 5px 0; color: #1890ff">
      {{ uploadParams.acceptTxt }}
    </div>

    <el-upload
      ref="refUpload"
      :multiple="uploadParams.limit > 1"
      :limit="uploadParams.limit"
      :accept="uploadParams.accept"
      action=""
      :auto-upload="false"
      :list-type="uploadParams.listType"
      v-model:file-list="fileList"
      :disabled="dg.disabled"
      @change="handleChange"
      @exceed="handleExceed"
      @remove="handleRemove"
      :drag="uploadParams.listType !== 'picture-card'">
      <el-icon v-if="uploadParams.listType === 'picture-card'">
        <Plus />
      </el-icon>
      <!-- 显示图标 -->
      <template v-if="uploadParams.listType === 'picture-card'" #file="{ file }">
        <img v-if="file.raw.type.startsWith('image/')" :src="file.url" class="el-upload-list__item-thumbnail" />
        <div v-else style="display: flex; align-items: center; justify-content: center; width: 100%">
          <img :src="handleShowIcon(file.name)" class="el-upload-list__item-thumbnail" style="width: 75%" />
        </div>
        <!-- 图片上按钮 -->
        <span class="el-upload-list__item-actions">
          <span class="el-upload-list__item-preview" @click="handlePreview(file)">
            <el-icon><ZoomIn /></el-icon>
          </span>
          <span class="el-upload-list__item-delete" @click="handleRemove(file)">
            <el-icon><Delete /></el-icon>
          </span>
        </span>
      </template>
      <!-- 拖拽导入 -->
      <div v-if="uploadParams.listType !== 'picture-card'">
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          {{ $t("将文件拖到此处，或") }} <em>{{ $t("点击上传") }}</em>
        </div>
        <!-- 导入文件提示信息 -->
        <div v-if="uploadParams.acceptTxt" class="el-upload__tip" style="color: red">
          {{ uploadParams.acceptTxt }}
        </div>
      </div>
    </el-upload>

    <template #footer>
      <szd-button label="下载模板" type="primary" @click="handleDownloadTM" v-if="uploadParams.TMCode" />
      <szd-button label="确定" type="primary" :disable="dg.disabled" @click="submitForm" />
      <szd-button label="取消" type="primary" @click="handleCloseForm" />
    </template>
  </el-dialog>
</template>

<script setup>
  import { onMounted, ref } from "vue";
  import { $m, $mS, $mW, $t } from "../../common/utils/globalConfig";
  import { downloadTemplate, uploadFile } from "../api/upload";
  import { szdMsgBox } from "../msgBox/msgBox";
  import szdDate from "../../common/tools/date";
  import szdStoreCookie from "../../common/store/storeCookie";
  import szdTool from "../../common/tools/tool";
  import { szdFileView } from "../../components/fileView/fileView";

  const props = defineProps({
    updParams: {
      type: Object,
      default: {}
    }
  });

  const emit = defineEmits(["uploadResult", "closeDialog"]);
  //上传文件控件
  const refUpload = ref();

  //窗口对象
  const dg = ref({
    open: false,
    disabled: false,
    //设置上传的请求头部
    header: { Authorization: "Bearer " + szdStoreCookie.getToken() },
    action: "/core/common/file/upload" //上传地址
  });

  //上传参数
  const uploadParams = ref({
    limit: 1, //最大上传文件数
    fileSize: undefined, //文件大小-KB
    fileSizeKb: "",
    dimension: [], //尺寸[宽-最小，宽-最大，高-最小，高-最大]
    accept: "", //上传文件类型
    acceptTxt: "", //提示信息
    extensions: [], //文件后缀
    uploadUrl: "", //上传地址
    typeCode: "", //附件类型
    filePath: "", //文件路径
    bussId: "", //业务id
    custParam: {}, //自定义参数
    showMsgBox: true, //显示消息
    listType: "text", //文件列表的类型
    TMCode: "", //下载模板
    title: "", //标题
    dialogWidth: 400, //窗口宽度
    dialogHeight: 450 //窗口高度
  });
  //上传文件清单
  const fileList = ref([]);
  const fileUpload = ref([]);
  //卡片图标
  const fileTypeIcon = szdTool.getFileTypeIcon();

  onMounted(() => {
    initUploadParam(props.updParams);
  });

  //初始化上传参数
  const initUploadParam = infoParam => {
    initData();
    //上传数据参数
    if (!infoParam.uploadUrl && !infoParam.typeCode) {
      $m("CORE_CLIENT.E079"); //上传地址参数不能为空
      return;
    }

    if (infoParam.limit && infoParam.limit > 1) uploadParams.value.limit = infoParam.limit;
    if (infoParam.fileSize && infoParam.fileSize > 0) {
      uploadParams.value.fileSize = infoParam.fileSize * 1024;
      uploadParams.value.fileSizeKb = infoParam.fileSize;
    }
    if (infoParam.dimension && Array.isArray(infoParam.dimension) && infoParam.dimension.length === 4) {
      uploadParams.value.dimension = infoParam.dimension;
    }
    if (infoParam.accept) {
      uploadParams.value.accept = infoParam.accept;
      uploadParams.value.acceptTxt = $t("提示：仅允许导入") + uploadParams.value.accept + $t("格式文件！");
    }
    if (infoParam.acceptTxt) uploadParams.value.acceptTxt = infoParam.acceptTxt;
    if (infoParam.extensions && Array.isArray(infoParam.extensions)) {
      for (let i = 0; i < infoParam.extensions.length; i++) {
        uploadParams.value.extensions.push(infoParam.extensions[i].toString().toLowerCase());
      }
    }
    uploadParams.value.listType = ["text", "picture", "picture-card"].includes(infoParam.listType) ? infoParam.listType : "text";
    uploadParams.value.uploadUrl = infoParam.uploadUrl ? infoParam.uploadUrl : "/core/common/file/upload";
    uploadParams.value.bussId = infoParam.bussId;
    uploadParams.value.typeCode = infoParam.typeCode;
    uploadParams.value.filePath = infoParam.filePath;
    uploadParams.value.custParam = infoParam.custParam;
    if (infoParam.showMsgBox === false) uploadParams.value.showMsgBox = infoParam.showMsgBox;
    if (infoParam.TMCode) uploadParams.value.TMCode = infoParam.TMCode;
    if (infoParam.title) uploadParams.value.title = infoParam.title;
    if (infoParam.dialogWidth && infoParam.dialogWidth > 10) uploadParams.value.dialogWidth = infoParam.dialogWidth;
    if (infoParam.dialogHeight && infoParam.dialogHeight > 10) uploadParams.value.dialogHeight = infoParam.dialogHeight;
    dg.value.open = true;
  };

  //下载模版
  const handleDownloadTM = () => {
    downloadTemplate(uploadParams.value.TMCode).then(response => {
      // 利用a标签自定义下载文件名
      const link = document.createElement("a");
      // 创建Blob对象，设置文件类型
      let blob = new Blob([response], {
        type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8"
      });
      let objectUrl = URL.createObjectURL(blob); // 创建URL
      link.href = objectUrl;
      link.download = uploadParams.value.TMCode + "_" + szdDate.format(undefined, "YYYYMMDDHHmmssSSS"); // 自定义文件名
      link.click(); // 下载文件
      URL.revokeObjectURL(objectUrl); // 释放内存
      $m("CORE_CLIENT.S010"); //导出文件成功
    });
  };

  //文件上传
  const submitForm = () => {
    if (fileUpload.value.length === 0) {
      $mW("请选择上传文件");
      return;
    }
    dg.value.disabled = true;
    let uploadObj = {
      bussId: uploadParams.value.bussId,
      typeCode: uploadParams.value.typeCode,
      filePath: uploadParams.value.filePath,
      custParam: uploadParams.value.custParam,
      fileUpload: fileUpload.value
    };
    uploadFile(uploadParams.value.uploadUrl, uploadObj).then(response => {
      emit("uploadResult", response);
      if (uploadParams.value.showMsgBox) {
        if (response && response.data && response.data.length > 0) {
          szdMsgBox(response.data).then(() => {});
        } else {
          $mS("文件上传完成");
        }
      }
      dg.value.open = false;
    });
  };

  //检查文件和调整为上传
  const handleChange = (file, files) => {
    const _filesLen = files.length - 1;
    //检查文件名是否重复
    if (fileList.value.find(r => r.name === file.name)) {
      $mW("存在相同的文件名");
      files.splice(_filesLen, 1);
      return;
    }
    //检查文件后缀
    if (uploadParams.value.extensions.length > 0) {
      const _lastIndex = file.name.lastIndexOf(".");
      if (
        _lastIndex === -1 ||
        _lastIndex === file.name.length - 1 ||
        !uploadParams.value.extensions.includes(file.name.substring(_lastIndex + 1).toLowerCase())
      ) {
        $mW("文件不正确");
        files.splice(_filesLen, 1);
        return;
      }
    }
    //检查文件大小
    if (uploadParams.value.fileSize && uploadParams.value.fileSize > 0 && uploadParams.value.fileSize < file.size) {
      $m("CORE_CLIENT.E029", uploadParams.value.fileSizeKb); //上传文件大小不能大于 & KB
      files.splice(_filesLen, 1);
      return;
    }
    //生成上传文件
    const fileReader = new FileReader();
    fileReader.readAsDataURL(file.raw);
    fileReader.onload = event => {
      //检查尺寸
      if (uploadParams.value.dimension.length === 4) {
        const img = new Image();
        img.src = event.target.result;
        img.onload = () => {
          const [width_0, width_1, height_0, height_1] = uploadParams.value.dimension;
          if (img.width < width_0 || img.width > width_1 || img.height < height_0 || img.height > height_1) {
            $m("CORE_CLIENT.E016", [width_0, height_0, width_1, height_1]); //图片尺寸限制为 & * & 到 & * &
            files.splice(_filesLen, 1);
          } else {
            fileUpload.value.push({ fileName: file.name, fileBase64: event.target.result });
          }
        };
      } else {
        fileUpload.value.push({ fileName: file.name, fileBase64: event.target.result });
      }
    };
  };

  //移除文件
  const handleRemove = file => {
    const _index = fileUpload.value.findIndex(r => r.fileName === file.name);
    if (_index > -1) {
      fileUpload.value.splice(_index, 1);
    }
    if (uploadParams.value.listType === "picture-card") {
      const _index2 = fileList.value.findIndex(r => r.name === file.name);
      if (_index2 !== -1) {
        fileList.value.splice(_index2, 1);
      }
    }
  };

  //预览文件
  const handlePreview = file => {
    if (file.url) szdFileView({ srcBlob: file.url, fileName: file.name });
  };

  //报错监控
  const handleExceed = () => {
    $mW("文件超过允许数量");
  };

  //显示文件图标
  const handleShowIcon = fileName => {
    const _lastIndex = fileName.lastIndexOf(".");
    if (_lastIndex === -1) return fileTypeIcon["obj"];
    const ext = fileName.substring(_lastIndex + 1).toLowerCase();
    return ext && fileTypeIcon[ext] ? fileTypeIcon[ext] : fileTypeIcon["obj"];
  };

  //初始化数据
  const initData = () => {
    dg.value.disabled = false;
    uploadParams.value = {
      limit: 1, //最大上传文件数
      fileSize: undefined, //文件大小
      fileSizeKb: "",
      dimension: [], //尺寸[宽-最小，宽-最大，高-最小，高-最大]
      accept: "", //上传文件类型 ".xls,.xlsx"
      acceptTxt: "", //提示信息
      extensions: [], //文件后缀
      listType: "text", //文件列表的类型
      uploadUrl: "", //上传地址
      typeCode: "", //附件类型
      filePath: "", //文件路径
      bussId: "", //业务id
      custParam: {}, //业务id
      showMsgBox: true, //显示消息盒子
      TMCode: "", //下载模板
      title: "", //标题
      dialogWidth: 400, //窗口宽度
      dialogHeight: 450 //窗口高度
    };
    fileList.value = [];
    fileUpload.value = [];
  };

  const handleCloseForm = () => {
    dg.value.open = false;
  };

  const handleClose = () => {
    refUpload.value.clearFiles();
    fileList.value = [];
    fileUpload.value = [];
    emit("closeDialog");
  };
</script>
